﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using C1.Win.C1FlexGrid;
using C1.Win.C1Command;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        bool rangeSelection = false;
        C1FlexGrid activeGrid = null;
        C1FlexGrid startDragingGrid = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            Initialize(c1FlexGrid1);
            Initialize(c1FlexGrid2);
            Initialize(c1FlexGrid3);
            Initialize(c1FlexGrid4);

            activeGrid = (C1FlexGrid)dtMap.SelectedTab.Controls[0].Controls[3];
            startDragingGrid = activeGrid;

            DragAndDropForm.MouseMoveChanged += new MouseMoveSecondHandler(DragAndDropForm_MouseMove);
            DragAndDropForm.MouseUpChanged += new MouseUpSecondHandler(DragAndDropForm_MouseUpSecond);

        }
        private void Initialize(C1FlexGrid grd)
        {
            grd.Rows.Count = grd.Cols.Count = 11;
            grd.Rows.Fixed = grd.Cols.Fixed = 1;
            grd.AllowEditing = false;
            grd.HighLight = HighLightEnum.Never;

            grd.Click += new EventHandler(grdMap_Click);
            grd.MouseUp += new MouseEventHandler(grd_MouseUp);

            grd.MouseMove += Grid_MouseMove;
            grd.MouseDown += Grid_MouseDown;

            Reset(grd);
        }

        void grd_MouseUp(object sender, EventArgs e)
        {
            rangeSelection = false;
        }

        private void Reset(C1FlexGrid grd)
        {
            for (int nRow = grd.Rows.Fixed; nRow < grd.Rows.Count; nRow++)
            {
                for (int nCol = grd.Rows.Fixed; nCol < grd.Rows.Count; nCol++)
                {
                    int nPos = ((nRow - 1) * grd.Cols.Count - 1) + nCol;

                    grd.SetData(nRow, nCol, nPos);

                    grd.SetCellStyle(nRow, nCol, grd.Styles.Normal);
                }
            }
        }

        void grdMap_Click(object sender, EventArgs e)
        {
            C1FlexGrid grd = (C1FlexGrid)sender;

            if (((CheckBox)GetControl(typeof(CheckBox))).Checked)
            {
                CellStyle style = grd.GetCellStyle(grd.Row, grd.Col);

                if (style == null || !style.Name.Equals("Highlight"))
                    grd.SetCellStyle(grd.Row, grd.Col, grd.Styles.Highlight);
                else
                    grd.SetCellStyle(grd.Row, grd.Col, grd.Styles.Normal);
            }
        }

        private Control GetControl(Type type)
        {
            foreach (Control ctrl in dtMap.SelectedTab.Controls)
                if (ctrl.GetType() == typeof(C1.Win.C1Sizer.C1Sizer))
                    foreach (Control ctrl2 in ctrl.Controls)
                        if (ctrl2.GetType() == type)
                            return ctrl2;

            return null;
        }

        private void cmdClear_Click(object sender, EventArgs e)
        {
            C1FlexGrid grd = (C1FlexGrid)GetControl(typeof(C1FlexGrid));

            int nRow = -1, nCol = -1;

            while (GetNextSelectedPos(grd, ref nRow, ref nCol))
                grd.SetData(nRow, nCol, "");
        }

        private bool GetNextSelectedPos(C1FlexGrid grd, ref int nRow, ref int nCol)
        {
            CheckBox chkBox = (CheckBox)GetControl(typeof(CheckBox));

            if (chkBox.Checked)
            {
                if (nRow == -1)
                {
                    nRow = grd.Rows.Fixed;
                    nCol = 0;
                }

                for (; nRow < grd.Rows.Count; nRow++)
                    for (nCol++; nCol < grd.Cols.Count; nCol++)
                    {
                        CellStyle style = grd.GetCellStyle(nRow, nCol);

                        if (style != null && style.Name.Equals("Highlight"))
                            return true;
                    }
            }
            else
            {
                if (nRow == -1)
                {
                    nRow = grd.Row;
                    nCol = grd.Col - 1;
                }

                for (; nRow <= grd.RowSel; nRow++)
                {
                    for (nCol++; nCol <= grd.ColSel; )
                        return true;

                    nCol = grd.Col - 1;
                }
            }

            return false;
        }

        private void cmdReset_Click(object sender, EventArgs e)
        {
            C1FlexGrid grd = (C1FlexGrid)GetControl(typeof(C1FlexGrid));

            Reset(grd);
        }

        private List<Rectangle> GetSelectedCells()
        {
            C1FlexGrid grd = (C1FlexGrid)GetControl(typeof(C1FlexGrid));

            int nRow = grd.Rows.Fixed, nCol = grd.Cols.Fixed;

            List<Rectangle> lstRect = new List<Rectangle>();

            while (GetNextSelectedPos(grd, ref nRow, ref nCol))
                lstRect.Add(grd.GetCellRect(nRow, nCol));

            return lstRect;
        }

        private void grdMap_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(System.String)))
            {
                C1FlexGrid grd = (C1FlexGrid)sender;

                Object item = (object)e.Data.GetData(typeof(System.String));

                string[] saItems = item.ToString().Split('\t');

                Point pt = grd.PointToClient(new Point(e.X, e.Y));

                HitTestInfo hti = grd.HitTest(pt);
            }
        }


        #region Nase dodato


        void DragAndDropForm_MouseUpSecond()
        {
            if (DalMoze())
            {
                if (startDragingGrid != null)
                foreach (var c in GetSelectedCellsIndexes(startDragingGrid))
                    {
                        startDragingGrid.SetData(c.x, c.y, "");
                        startDragingGrid.SetCellStyle(c.x, c.y, startDragingGrid.Styles.Normal);
                    }

                Point pt = new Point(Cursor.Position.X, Cursor.Position.Y);
                pt = activeGrid.PointToClient(pt);
                int clickedColumnIndex = activeGrid.HitTest(pt).Column;
                int clickedRowIndex = activeGrid.HitTest(pt).Row;

                activeGrid.SetData(clickedRowIndex, clickedColumnIndex, DragAndDropForm.mainDragAndDropForm.value);

                foreach (DragAndDropForm f in DragAndDropForm.dragAndDropForms)
                {

                    activeGrid.SetData(clickedRowIndex + f.offsetY, clickedColumnIndex + f.offsetX, f.value);
                }
            }
            else
            {

            }

            DragAndDropForm.ClearForms();
        }

        void DragAndDropForm_MouseMove()
        {
            Point pt = new Point(Cursor.Position.X, Cursor.Position.Y);
            pt = dtMap.PointToClient(pt);

            foreach (C1DockingTabPage c in dtMap.Controls)
            {

                if ((pt.X > c.TabBounds.X && pt.X < (c.TabBounds.X + c.TabBounds.Width)) && (pt.Y > c.TabBounds.Y && pt.Y < (c.TabBounds.Y + c.TabBounds.Height)))
                {
                    dtMap.SelectedTab = c;
                    break;
                }
            }

            if (DalMoze())
                DragAndDropForm.setBackground(Color.Blue);
            else
                DragAndDropForm.setBackground(Color.Silver);
        }

        private bool DalMoze()
        {
            Point pt = new Point(Cursor.Position.X, Cursor.Position.Y);
            pt = activeGrid.PointToClient(pt);
            int clickedColumnIndex = activeGrid.HitTest(pt).Column;
            int clickedRowIndex = activeGrid.HitTest(pt).Row;

            if (clickedColumnIndex > 0 && clickedRowIndex > 0)
            {
                object value = activeGrid[clickedRowIndex, clickedColumnIndex];

                if (value == null || value.ToString() == "") // ima mesta za root
                {
                    foreach (DragAndDropForm f in DragAndDropForm.dragAndDropForms)
                    {

                        value = activeGrid[f.offsetY + clickedRowIndex, clickedColumnIndex + f.offsetX];

                        if (value != null && value.ToString() != "")
                            return false;
                    }

                    return true;
                }
            }

            return false;
        }


        bool dragging = false;

        private void StartDragging() //na button down
        {
            dragging = true;

            Cursor.Current = Cursors.Hand;


        }

        void EndDragging() //na button up
        {
            dragging = false;
            Cursor.Current = Cursors.Default;
        }

        private List<CellCoordinate> GetSelectedCellsIndexes(C1FlexGrid grd)
        {
            CheckBox chkBox = (CheckBox)GetControl(typeof(CheckBox));
            List<CellCoordinate> selectedCells = new List<CellCoordinate>();

            int rowCount = grd.Rows.Count;
            int colCount = grd.Cols.Count;

            for (int i = 0; i < rowCount; i++)
                for (int j = 0; j < colCount; j++)
                {

                    CellStyle style = grd.GetCellStyle(i, j);

                    if (style != null && style.Name.Equals("Highlight"))
                        selectedCells.Add(new CellCoordinate(i, j, grd.Rows[i][j]));

                }

            return selectedCells;
        }

        private void Grid_MouseMove(object sender, MouseEventArgs e)
        {

            if (e.Button == System.Windows.Forms.MouseButtons.Left && dragging)
            {
                startDragingGrid = activeGrid;
                List<CellCoordinate> list = GetSelectedCellsIndexes(activeGrid);

                foreach (var cell in list)
                {
                    if (cell.x != DragAndDropForm.rootX || cell.y != DragAndDropForm.rootY)
                    {
                        DragAndDropForm ff = new DragAndDropForm(cell.y - DragAndDropForm.rootY, cell.x - DragAndDropForm.rootX, cell.value);
                        ff.StartPosition = FormStartPosition.CenterScreen;

                        DragAndDropForm.dragAndDropForms.Add(ff);
                    }
                }

                DragAndDropForm.setFormsSize();
                DragAndDropForm.SowsForms();

                dragging = false;
            }
            else if (rangeSelection == true)
            {
                Point pt = new Point(e.X, e.Y);
                int clickedColumnIndex = activeGrid.HitTest(e.X, e.Y).Column;
                int clickedRowIndex = activeGrid.HitTest(e.X, e.Y).Row;

                if (clickedColumnIndex < 1 || clickedRowIndex < 1)
                    return;

                CellStyle style = activeGrid.GetCellStyle(clickedRowIndex, clickedColumnIndex);

                activeGrid.SetCellStyle(clickedRowIndex, clickedColumnIndex, activeGrid.Styles.Highlight);

            }

            DragAndDropForm.SetPositions();

        }


        private void Grid_MouseDown(object sender, MouseEventArgs e)
        {

            CheckBox chkBox = (CheckBox)GetControl(typeof(CheckBox));

            DragAndDropForm.ClearForms();

            List<CellCoordinate> selectedCells = GetSelectedCellsIndexes(activeGrid);
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                selectedCells = GetSelectedCellsIndexes(activeGrid);

                Point pt = new Point(e.X, e.Y);
                int clickedColumnIndex = activeGrid.HitTest(e.X, e.Y).Column;
                int clickedRowIndex = activeGrid.HitTest(e.X, e.Y).Row;

                if (clickedRowIndex < 1 || clickedColumnIndex < 1)
                    return;

                CellCoordinate clickedCell = new CellCoordinate(clickedRowIndex, clickedColumnIndex, activeGrid[clickedRowIndex, clickedColumnIndex]);

                if (selectedCells.Find(x => x.x == clickedCell.x && x.y == clickedCell.y) != null) // if cell is inside selected cells begin drag
                {
                    if (clickedColumnIndex > 0 && clickedRowIndex > 0)
                    {
                        foreach (CellCoordinate cc in selectedCells)
                        {
                            if (cc.x == clickedRowIndex && cc.y == clickedColumnIndex)
                            {
                                DragAndDropForm.rootX = cc.x;
                                DragAndDropForm.rootY = cc.y;

                                DragAndDropForm f = new DragAndDropForm(0, 0, cc.value);
                                DragAndDropForm.mainDragAndDropForm = f;



                                Rectangle rect = activeGrid.GetCellRect(cc.x, cc.y);
                                f.Height = rect.Height;
                                f.Width = rect.Width;

                                f.MaximumSize = new Size(rect.Width, rect.Height);
                                f.MinimumSize = new Size(rect.Width, rect.Height);

                                StartDragging();
                                break;
                            }

                        }
                    }
                }

                else // begin select
                {
                    if (chkBox.Checked == false)
                    {
                        rangeSelection = true;

                        for (int i = 1; i < activeGrid.Rows.Count; i++)
                            for (int j = 1; j < activeGrid.Cols.Count; j++)
                                activeGrid.SetCellStyle(i, j, activeGrid.Styles.Normal);

                        activeGrid.Refresh();
                    }
                }



            }


        }

        #endregion

        private void dtMap_SelectedTabChanged(object sender, EventArgs e)
        {
            C1DockingTab dtab = (C1DockingTab)sender;

            C1.Win.C1Sizer.C1Sizer sizer = (C1.Win.C1Sizer.C1Sizer)dtab.SelectedTab.Controls[0];// (C1.Win.C1Sizer.C1Sizer)dtab.Controls[0].Controls[0];
            activeGrid = (C1FlexGrid)sizer.Controls[3];
        }


    }


    class CellCoordinate
    {
        public int x, y;
        public object value;

        public CellCoordinate(int x, int y, object value)
        {
            this.x = x;
            this.y = y;
            this.value = value;
        }
    }
}
